Chrono (v1)
A natural language date parser in Javascript, designed for extracting date information from any given text. (Java version is also available here)
Chrono supports most date and time formats, such as :
- Today, Tomorrow, Yesterday, Last Friday, etc
- 17 August 2013 - 19 August 2013
- This Friday from 13:00 - 16.00
- 5 days ago
- 2 weeks from now
- Sat Aug 17 2013 18:40:39 GMT+0900 (JST)
- 2014-11-30T08:15:30-05:30
Installation
Just run:
$ npm i --save chrono-node
And start using chrono:
var chrono = require('chrono-node');
chrono.parseDate('An appointment on Sep 12-13');
Swift
Try using the community-made chrono-swift wrapper.
Usage
Simply pass a string to function chrono.parseDate
or chrono.parse
.
var chrono = require('chrono-node');
chrono.parseDate('An appointment on Sep 12-13');
chrono.parse('An appointment on Sep 12-13');
Reference Date
Today's "Friday" is different from last month's "Friday".
The meaning of the referenced dates depends on when they are mentioned.
Chrono lets you define a reference date using chrono.parse(text, ref)
and chrono.parseDate(text, ref)
.
chrono.parseDate('Friday', new Date(2012, 7, 23));
chrono.parseDate('Friday', new Date(2012, 7, 1));
Parsing Options
forwardDate
(boolean) to assume the results should happen after the reference date (forward into the future)
var referenceDate = new Date(2012, 7, 25);
chrono.parseDate('Friday', referenceDate);
chrono.parseDate('Friday', referenceDate, { forwardDate: true });
timezones
(Map) to override Chrono's default timezone abbriviation mapping. The value should be the timezone offset in minutes (between -720 to 720).
chrono.parse('Friday at 2 pm IST', refDate, { timezones: { 'IST': 330 } })[0].start.get('timezoneOffset');
chrono.parse('Friday at 2 pm IST', refDate, { timezones: {'IST': 60 } })[0].start.get('timezoneOffset');
Detailed Parsed Results
The function chrono.parse
returns detailed parsing results as objects of class chrono.ParsedResult
.
var results = chrono.parse('I have an appointment tomorrow from 10 to 11 AM');
results[0].index;
results[0].text;
results[0].ref;
results[0].start.date();
results[0].end.date();
ParsedResult
start
The parsed date components as a ParsedComponents objectend
Similar to start
but can be null.index
The location within the input text of this resulttext
The text this result that appears in the inputref
The reference date of this result
ParsedComponents
A group of found date and time components (year, month, hour, etc). ParsedComponents objects consist of knownValues
and impliedValues
.
assign(component, value)
Set known value to the componentimply(component, value)
Set implied value to the componentget(component)
Get known or implied value for the componentisCertain(component)
return true if the value of the component is known.date()
Create a javascript Date
var results = new chrono.parse('2016-03-08T01:16:07+02:00');
results[0].start.assign('timezoneOffset', 0);
var d = results[0].start.date();
d.toString();
Strict vs Casual
Chrono comes with strict
mode that parse only formal date patterns.
chrono.strict.parseDate('Today');
chrono.strict.parseDate('Friday');
chrono.strict.parseDate('2016-07-01');
chrono.strict.parseDate('Jul 01 2016');
chrono.parseDate('Today');
chrono.casual.parseDate('Friday');
chrono.casual.parseDate('2016-07-01');
chrono.casual.parseDate('Jul 01 2016');
Choosing Locale
By default, Chrono is configurated to parse different date formats from muliple languages out-off-box. However, by using predefined locale options, you can increase parsing accuracy.
Handling different date format for UK / US is a good example.
chrono.parseDate('6/10/2018');
chrono.en.parseDate('6/10/2018');
chrono.en_GB.parseDate('6/10/2018');
chrono.de.parseDate('6/10/2018');
Current supported locale options are: en
, en_GB
, de
, pt
, es
, fr
, ja
Customize Chrono
Chrono’s extraction pipeline are mainly separated into 'parse' and ‘refine’ phases. During parsing, ‘parsers’ (Parser
) are used to extract patterns from the input text. The parsed results (ParsedResult) are the combined, sorted, then refine using ‘refiners’ (Refiner
). In the refining phase, the results can be combined, filtered-out, or attached with additional information.
Parser
Parser is a module for low-level pattern-based parsing. Ideally, each parser should be designed to handle a single specific date format. User can add new type of parsers for supporting new date formats or languages.
var christmasParser = new chrono.Parser();
christmasParser.pattern = function () { return /Christmas/i; };
christmasParser.extract = function(text, ref, match, opt) {
return new chrono.ParsedResult({
ref: ref,
text: match[0],
index: match.index,
start: {
day: 25,
month: 12,
}
});
};
var custom = new chrono.Chrono();
custom.parsers.push(christmasParser);
custom.parseDate("I'll arrive at 2.30AM on Christmas night");
To create a custom parser, override pattern
and extract
methods on an object of class chrono.Parser
.
- The
pattern
method must return RegExp
object of searching pattern. - The
extract
method will be called with the
match object when the pattern is found. This function must create and return a result (or null to skip).
Refiner
Refiner is a higher level module for improving or manipulating the results. User can add a new type of refiner to customize Chrono's results or to add some custom logic to Chrono.
var guessPMRefiner = new chrono.Refiner();
guessPMRefiner.refine = function(text, results, opt) {
results.forEach(function (result) {
if (!result.start.isCertain('meridiem') &&
result.start.get('hour') >= 1 && result.start.get('hour') < 4) {
result.start.assign('meridiem', 1);
result.start.assign('hour', result.start.get('hour') + 12);
}
});
return results;
};
var custom = new chrono.Chrono();
custom.refiners.push(guessPMRefiner);
custom.parseDate("This is at 2.30");
custom.parseDate("This is at 2.30 AM");
In the example, a custom refiner is created for assigning PM to parsing results with ambiguous meridiem. The refine
method of the refiner class will be called with parsing results (from parsers or other previous refiners). The method must return an array of the new results (which, in this case, we modified those results in place).
Development Guides
This guide explains how to setup chrono project for prospective contributors.
$ git clone https://github.com/wanasit/chrono.git chrono
$ cd chrono
$ npm install
Parsing date from text is complicated. Sometimes, a small change can have effects on unexpected places. So, Chrono is a heavily tested library. Commits that break a test shouldn't be allowed in any condition.
Chrono's unit testing is based-on Jest.
$ npm run test
$ npm run watch
Chrono's source files is in src
directory. The built bundle (dist/*
) is created by running Webpack via the following command
$ npm run build